package com.jsz.peini.controller.app;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.jsz.peini.bean.sign.SignInfo;
import com.jsz.peini.bean.sign.SignInfoExample;
import com.jsz.peini.bean.sign.SignSet;
import com.jsz.peini.bean.sign.SignSetExample;
import com.jsz.peini.bean.sign.SignSetExample.Criteria;
import com.jsz.peini.bean.user.UserAccount;
import com.jsz.peini.common.constants.Constants;
import com.jsz.peini.common.util.DateTimeUtils;
import com.jsz.peini.common.util.PeiniUtils;
import com.jsz.peini.mapper.coupon.CouponGetMapper;
import com.jsz.peini.mapper.order.GoldHistoryMapper;
import com.jsz.peini.mapper.order.ScoreHistoryMapper;
import com.jsz.peini.mapper.sign.SignInfoMapper;
import com.jsz.peini.mapper.sign.SignSetDetailMapper;
import com.jsz.peini.mapper.sign.SignSetMapper;
import com.jsz.peini.mapper.user.UserAccountMapper;
import com.jsz.peini.redis.util.SignRedisUtil;
import com.jsz.peini.redis.util.UserRedisUtil;
import com.jsz.peini.service.sign.SignInfoService;
import com.jsz.peini.service.user.UserAccountService;
import com.jsz.peini.vo.UserVo;

/**
 * @author Han Guohong
 * @version 2017-2-14 上午11:31:08
 * 类说明
 */
@Controller
public class SignController {
	private static final Logger logger = LoggerFactory.getLogger(SignController.class);
	@Resource
	private SignInfoService signInfoService;
	@Resource
	private SignSetMapper signSetMapper;
	@Resource
	private SignSetDetailMapper signSetDetailMapper;
	@Resource
	private UserAccountMapper userAccountMapper;
	@Resource
	private GoldHistoryMapper goldHistoryMapper;
	@Resource
	private ScoreHistoryMapper scoreHistoryMapper;
	@Resource
	private SignInfoMapper signInfoMapper;
	@Resource
	private UserAccountService userAccountService;
	@Resource
	private CouponGetMapper couponGetMapper;

	/**
	 * 每日签到
	 * @param userId 用户id,
	 * @author zq
	 * @throws IOException 
	 */
	@RequestMapping(value="/insertSignInfo")
	@ResponseBody
	public Object insertSignInfo(HttpServletRequest request,String userId,
			@RequestParam(value="setDate") String setDate
			){
		LinkedHashMap<String, Object> infoMap = new LinkedHashMap<String, Object>();
		infoMap.put("resultCode", Constants.SUCCESS);
		infoMap.put("resultDesc", "成功");
		try {
			JSONObject obj = PeiniUtils.validToken(userId);
			if(obj.getInteger("resultCode") != 1){
				return obj;
			}
			userId = obj.getString("userId");
			
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			
			UserVo userVo = UserRedisUtil.getUserVoByUserId(userId);
			if(userVo == null){
				infoMap.put("resultCode", Constants.EXCEPTION);
				infoMap.put("resultDesc", Constants.EXCEPTION_DESC);
				return infoMap;
			}
			
			boolean afterSign = isAfterSign(setDate);
			if(afterSign == true){
				infoMap.put("resultCode", Constants.FAIL);
				infoMap.put("resultDesc", "请设置您的手机时间，只能当天签到");
				return infoMap;
			}
			
			UserAccount userAccount = userAccountMapper.selectByPrimaryKey(Integer.parseInt(userVo.getAcountId()));
			
			//判断是否签到
			Calendar calendar = Calendar.getInstance();
			String lastD = SignRedisUtil.getLastSignDate(userId);
			if(StringUtils.isBlank(lastD)){//没有签过到，直接签到
				
				boolean flag = isAddSign(setDate);
				
				if(flag == true){//补签到
					String backStr = signInfoService.addSignInfo(setDate, userId, userAccount);
					if(StringUtils.isNotBlank(backStr)){
						infoMap.put("dayAward", backStr);
						infoMap.put("resultCode", Constants.SUCCESS);
						infoMap.put("resultDesc", Constants.SUCCESS_DESC);
					}else {
						infoMap.put("resultCode", Constants.EXCEPTION);
						infoMap.put("resultDesc", Constants.EXCEPTION_DESC);
						return infoMap;
					}
				}else{//非补签到
					String backStr = signInfoService.nowSign(userId, userAccount);
					if(StringUtils.isNotBlank(backStr)){
						infoMap.put("dayAward", backStr);
					}
					infoMap.put("resultCode", Constants.SUCCESS);
					infoMap.put("resultDesc", Constants.SUCCESS_DESC);
				}
			}else{
				//判断是否是重复签到
				boolean flag = isExistSign(setDate, lastD);
				if(flag == true){//重复签到
					infoMap.put("resultCode", Constants.FAIL);
					infoMap.put("resultDesc", "已经签过到了，不允许重复签到");
					return infoMap;
				}else{
					flag = isAddSign(setDate);
					if(flag == true){//补签到
						String backStr = signInfoService.addSignInfo(setDate, userId, userAccount);
						if(StringUtils.isNotBlank(backStr)){
							infoMap.put("dayAward", backStr);
							infoMap.put("resultCode", Constants.SUCCESS);
							infoMap.put("resultDesc", Constants.SUCCESS_DESC);
						}else {
							infoMap.put("resultCode", Constants.EXCEPTION);
							infoMap.put("resultDesc", Constants.EXCEPTION_DESC);
							return infoMap;
						}
					}else{//非补签到
						String backStr = signInfoService.nowSign(userId, userAccount);
						if(StringUtils.isNotBlank(backStr)){
							infoMap.put("dayAward", backStr);
						}
						infoMap.put("resultCode", Constants.SUCCESS);
						infoMap.put("resultDesc", Constants.SUCCESS_DESC);
					}
				}
			}
		} catch (Exception e) {
			infoMap.put("resultCode", Constants.EXCEPTION);
			infoMap.put("resultDesc", "网络请求异常");
			logger.error(e.getMessage(),e);
		}
		return infoMap;
	}
	
	/**
	 * 返回用户签到列表
	 * @param userId 用户id,strDate 日期(格式:年:"2016" 月:"2016-05"),dateType 0:所有 1:全年 2:全月
	 * @author zq
	 * @throws IOException 
	 */
	@RequestMapping(value="/getUserSignInfo")
	@ResponseBody
	public Object getUserSignInfo(HttpServletRequest request,String userId,
			@RequestParam(value="start") String start,
			@RequestParam(value="end") String end
			){
		LinkedHashMap<String, Object> infoMap = new LinkedHashMap<String, Object>();
		infoMap.put("resultCode", Constants.SUCCESS);
		infoMap.put("resultDesc", "成功");
		try {
			JSONObject obj = PeiniUtils.validToken(userId);
			if(obj.getInteger("resultCode") != 1){
				return obj;
			}
			userId = obj.getString("userId");
			
			UserAccount userAccount = userAccountService.selectByUserId(userId);
			infoMap.put("score", userAccount.getScore().toString());
			
			List<String> setList = new ArrayList<String>();
			SignSetExample example = new SignSetExample();
			Criteria criteria = example.createCriteria();
			criteria.andSettypeEqualTo(2);
			criteria.andIsreleaseEqualTo(1);
			example.setOrderByClause("sign_loca asc");
			List<SignSet> list = signSetMapper.selectByExampleWithBLOBs(example);
			
			for (SignSet signSet : list) {
				setList.add(signSet.getMarkedwords());
			}
			
			infoMap.put("marks", setList);
			
			SignInfoExample infoExample = new SignInfoExample();
			com.jsz.peini.bean.sign.SignInfoExample.Criteria infoCriteria = infoExample.createCriteria();
			infoCriteria.andUserIdEqualTo(userId);
			infoCriteria.andSignDateBetween(DateTimeUtils.formatString2Date(start, "yyyy-MM-dd"), DateTimeUtils.formatString2Date(end, "yyyy-MM-dd"));
			List<SignInfo> infos = signInfoMapper.selectByExample(infoExample);
			
			List<String> signList = new ArrayList<>();
			//LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
			//List<Date> dates = findDates(DateTimeUtils.formatString2Date(start, "yyyy-MM-dd"), DateTimeUtils.formatString2Date(end, "yyyy-MM-dd"));
			List<Date> dates = DateTimeUtils.findDates(DateTimeUtils.formatString2Date(start, "yyyy-MM-dd"), DateTimeUtils.formatString2Date(end, "yyyy-MM-dd"));
			for (Date date : dates) {
				boolean flag = false;
				for (SignInfo info : infos) {
					if(date.equals(info.getSignDate())){
						flag = true;
					}
				}
				if(flag == true){
					signList.add("1");
					//map.put(DateTimeUtils.formatDateTime2String(date, "yyyy-MM-dd"), "1");
				}else{
					signList.add("0");
					//map.put(DateTimeUtils.formatDateTime2String(date, "yyyy-MM-dd"), "0");
				}
			}
			
			int cnt = SignRedisUtil.getSignDays(userId);
			infoMap.put("signDays", String.valueOf(cnt));
			infoMap.put("signList", signList);
			//logger.info(net.sf.json.JSONObject.fromObject(infoMap));
		} catch (Exception e) {
			infoMap.put("resultCode", Constants.EXCEPTION);
			infoMap.put("resultDesc", Constants.EXCEPTION_DESC);
			logger.error(e.getMessage(),e);
		}
		return infoMap;
	}
	
	/*private List<Date> findDates(Date dBegin, Date dEnd){  
		List lDate = new ArrayList();  
		lDate.add(dBegin);
		Calendar calBegin = Calendar.getInstance();  
		// 使用给定的 Date 设置此 Calendar 的时间  
		calBegin.setTime(dBegin);  
		Calendar calEnd = Calendar.getInstance();  
		// 使用给定的 Date 设置此 Calendar 的时间  
		calEnd.setTime(dEnd);  
		// 测试此日期是否在指定日期之后  
		while (dEnd.after(calBegin.getTime())){  
			// 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
			calBegin.add(Calendar.DAY_OF_MONTH, 1);  
			lDate.add(calBegin.getTime());  
		}  
		return lDate;  
	}  */
	
	/**
	 * 判断是否是补签到
	 * @author Han Guohong
	 * @param setDate
	 * @return
	 */
	private boolean isAddSign(String setDate){
		boolean flag = false;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date now = new Date(); 
			String today = sdf.format(now)+" 00:00:00";
			Date nowD = sdf.parse(today);		
			
			Date signD = sdf.parse(setDate);
			
			if(signD.before(nowD)){
				flag = true;
			}
			
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		return flag;
	}
	
	/**
	 * 是否超过当前时间
	 * @author Han Guohong
	 * @param setDate
	 * @return
	 */
	private boolean isAfterSign(String setDate){
		boolean flag = false;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date now = new Date(); 
			String today = sdf.format(now)+" 00:00:00";
			Date nowD = sdf.parse(today);		
			
			Date signD = sdf.parse(setDate);
			
			if(signD.after(nowD)){
				flag = true;
			}
			
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		return flag;
	}
	
	/**
	 * 判断是否重复签到
	 * @author Han Guohong
	 * @param setDate
	 * @param lastDay
	 * @return
	 */
	private boolean isExistSign(String setDate,String lastDay){
		boolean flag = false;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Date signD = sdf.parse(setDate);
			setDate = sdf.format(signD);
			
			if(setDate.equals(lastDay)){
				flag = true;
			}
			
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
		}
		
		return flag;
	}
}
